namespace tb
{

	namespace StringHelper
	{

		// ================================
		// Length
		// ================================

		template <typename C> size_t GetLength(const C* a_String);

		template <> 
		TB_INLINE size_t GetLength(const char* a_String) 
		{ 
			return strlen(a_String); 
		}

		template <> 
		TB_INLINE size_t GetLength(const wchar_t* a_String) 
		{ 
			return wcslen(a_String); 
		}

		// ================================
		// Clear
		// ================================

		template <typename C> void Clear(C* a_String, size_t a_Length);

		template <>
		TB_INLINE void Clear(char* a_String, size_t a_Length)
		{
			char* src = a_String;
			for (size_t i = 0; i < a_Length; i++)
			{
				*src++ = 0;
			}
		}

		template <>
		TB_INLINE void Clear(wchar_t* a_String, size_t a_Length)
		{
			char* src = (char*)a_String;
			for (size_t i = 0; i < a_Length; i++)
			{
				*src++ = 0;
				*src++ = 0;
			}
		}

		// ================================
		// Copy
		// ================================

		template <typename C, typename D> void Copy(C* a_Dst, const D* a_Src, int a_SrcLength);

		// copying (normal)

		template <>
		TB_INLINE void Copy(char* a_Dst, const char* a_Src, int a_SrcLength) 
		{ 
			strncpy(a_Dst, a_Src, a_SrcLength); 
		}

		template <>
		TB_INLINE void Copy(wchar_t* a_Dst, const wchar_t* a_Src, int a_SrcLength) 
		{ 
			wcsncpy(a_Dst, a_Src, a_SrcLength); 
		}

		// copying (conversion)

		template <>
		TB_INLINE void Copy(char* a_Dst, const wchar_t* a_Src, int a_SrcLength) 
		{ 
			char* dst = a_Dst;
			const char* src = (const char*)a_Src;
			for (int i = 0; i < a_SrcLength; i++)
			{
				*dst = *src;

				dst++;
				src += 2;
			}
		}

		template <>
		TB_INLINE void Copy(wchar_t* a_Dst, const char* a_Src, int a_SrcLength)
		{ 
			char* dst = (char*)a_Dst;
			const char* src = a_Src;
			for (int i = 0; i < a_SrcLength; i++)
			{
				*dst = *src;

				dst += 2;
				src++;
			}
		}

		// ================================
		// Safe copy
		// ================================

		template <typename C, typename D> void CopySafe(C* a_Dst, int a_DstMaximum, const D* a_Src, int a_SrcLength);

		template <>
		TB_INLINE void CopySafe(char* a_Dst, int a_DstMaximum, const char* a_Src, int a_SrcLength) 
		{ 
			int i;

			for (i = 0; i < a_SrcLength; i++)
			{
				if (i == (a_DstMaximum - 1) || a_Src[i] == 0) { break; }

				a_Dst[i] = a_Src[i];
			}
			a_Dst[i] = 0;
		}

		template <>
		TB_INLINE void CopySafe(wchar_t* a_Dst, int a_DstMaximum, const wchar_t* a_Src, int a_SrcLength) 
		{ 
			int i;

			for (i = 0; i < a_SrcLength; i++)
			{
				if (i == (a_DstMaximum - 1) || a_Src[i] == 0) { break; }

				a_Dst[i] = a_Src[i];
			}
			a_Dst[i] = 0;
		}

		// ================================
		// To lower
		// ================================

		template <typename C> C ToLower(const C& a_Src);

		template <>
		TB_INLINE char ToLower(const char& a_Src)
		{
			return (a_Src >= 'A' && a_Src <= 'Z') ? (a_Src + 32) : a_Src;
		}

		template <>
		TB_INLINE wchar_t ToLower(const wchar_t& a_Src)
		{
			return (a_Src >= 'A' && a_Src <= 'Z') ? (a_Src + 32) : a_Src;
		}

	}; // namespace StringHelper

}; // namespace tb